/**
 * 
 */
package com.vision.core.sv.serv.rpc.handler;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.Result;

import com.vision.core.cl.CoreValidators;
import com.vision.core.cm.data.Domain;
import com.vision.core.cm.db.data.User;
import com.vision.core.cm.exception.DataNotFoundException;
import com.vision.core.cm.exception.DispatchException;
import com.vision.core.sv.db.mgr.IDataManager;
import com.vision.core.sv.serv.dispatch.BaseActionHandler;

/**
 * @author Mark
 *
 */
public abstract class UserHandler<A extends Action<R>, R extends Result> extends BaseActionHandler<User, A, R> {

	@Autowired
	@Qualifier("userManager")
	public void setDataManager(IDataManager<User> dataManager) {
		super.setDataManager(dataManager);
	}
	
	@Override
	protected Domain getDomain() {
		return Domain.USER;
	}
	
	// Helpers *****************************************************************

	@SuppressWarnings("unchecked")
	protected void ensureNonExisting(User user) throws DispatchException {
		// Check by username
		User existingUser = dataManager.getById(user.getUsername());
		if (existingUser != null)
			throw new DispatchException("The username '" + user.getUsername() + "' is already in use.");
		
		// Check by email
		DetachedCriteria crit = DetachedCriteria.forClass(User.class);
		crit.add(Restrictions.ilike("email", user.getEmail(), MatchMode.EXACT));
		List<User> existinByEmail = dataManager.getTemplate().findByCriteria(crit);
		if (!existinByEmail.isEmpty())
			throw new DispatchException("The email address '" + user.getEmail() + "' is already in use.");
	}
	
	protected User ensureExisting(User user) throws DataNotFoundException {
		User existingUser = dataManager.getById(user.getUsername());
		if (existingUser == null)
			throw new DataNotFoundException("The User does not exist.");
		return existingUser;
	}
	
	protected static void checkUsername(String username) throws DispatchException {
		String v = username == null ? "" : username.trim();
		if (v.isEmpty())
			throw new DispatchException("Username must not be empty.");
		
		if (!v.matches(CoreValidators.USERNAME_REGEX))
			throw new DispatchException("The username does not follow a valid format.");
	}

}
